<template>
  <div class="my-checkbox-group" @mousedown="startDrag" @mouseup="endDrag">
    <slot></slot>
  </div>
</template>

<script>
export default {
  name: 'MyCheckboxGroup',
  props: {
    value: {
      type: Array,
      default: () => []
    }
  },
  data() {
    return {
      dragging: false,
      startValue: null,
      currentSelection: []
    }
  },
  provide() {
    return {
      checkboxGroup: this
    }
  },
  methods: {
    toggleCheckbox(value, checked) {
      let newValue = [...this.value]
      if (checked) {
        if (!newValue.includes(value)) {
          newValue.push(value)
        }
      } else {
        newValue = newValue.filter(item => item !== value)
      }
      this.$emit('input', newValue)
      this.$emit('change', newValue)
    },
    startDrag(startValue) {
      this.dragging = true
      this.startValue = startValue
      this.currentSelection = [...this.value]
    },
    endDrag(event) {
      if (!this.dragging) return
      this.dragging = false

      const endValue = this.getCheckboxValueFromEvent(event)
      if (this.startValue && endValue) {
        this.selectRange(this.startValue, endValue)
      }
      this.startValue = null
    },
    getCheckboxValueFromEvent(event) {
      const checkbox = event.target.closest('.my-checkbox-button')
      return checkbox ? checkbox.getAttribute('data-value') : null
    },
    selectRange(startValue, endValue) {
      const checkboxes = this.$el.querySelectorAll('.my-checkbox-button')
      const values = Array.from(checkboxes).map(checkbox => checkbox.getAttribute('data-value'))

      let startIndex = values.indexOf(startValue)
      let endIndex = values.indexOf(endValue)

      if (startIndex === -1 || endIndex === -1) return

      if (startIndex > endIndex) {
        ;[startIndex, endIndex] = [endIndex, startIndex]
      }

      const newValues = [...this.currentSelection]
      for (let i = startIndex; i <= endIndex; i++) {
        const value = values[i]
        if (!newValues.includes(value)) {
          newValues.push(value)
        }
      }

      this.$emit('input', newValues)
      this.$emit('change', newValues)
    }
  }
}
</script>

<style scoped>
.my-checkbox-group {
  display: flex;
  flex-wrap: wrap;
}
</style>
